#! /bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
#*===========================================================================*/
#*                                                                           */
#* Module Name:  rmcctrl                                                     */
#*                                                                           */
#* Description:                                                              */
#*      Script to manage the Resource Monitor & Control Daemon as            */
#*      an SRC subsystem.                                                    */
#*                                                                           */
#*===========================================================================*/
#*   @(#)37   1.20   src/rsct/rmc/mcdaemon/rmcctrl.sh, mcdaemon, rsct_rpyxh, rpyxht1f3 6/21/02 13:08:47 

# Set path to known value
PATH=/usr/sbin/rsct/bin:/usr/bin:/usr/sbin:/bin
export PATH

SS_PATH=/usr/sbin/rsct/bin			# path to subsystem daemons
CDEF_PATH=/usr/sbin/rsct/cfg/rmdefs	# path to cdef files
SUBSYS=ctrmc						# name of subsystem
SUBSYSGRP=rsct						# name of subsystem's group
RMGRP=rsct_rm						# group name for all RSCT resource managers
PROG=rmcd							# name of subsystem daemon
SPROG=rmcd_start					# name of subsystem daemon startup program
SECSUBSYS=ctcas						# security subsystem daemon
SECPROG=ctcasd						# name of security subsystem daemon
WAITTIME=30							# value of -w flag on mkssys
WAITLIMIT=40						# number of seconds to wait for
									# subsystems to stop

# get cluster name (1st token in lsclcfg ouput)

CTNAME=$(LC_ALL=C lsclcfg -x 2> /dev/null | sed -n -e"1s/^\([^ ]*\) .*$/\1/p")

CTNAME=${CTNAME:-IW}				# ensure a rational value

CFGDIR=/var/ct/$CTNAME/cfg			# path to directory that will contain cdb
CDBNAMESRC=mc.cdb					# source name
CDBBASE=mc.cdb
CDBNAMEDST=$CDBBASE					# destination name
MCALOG=/var/ct/$CTNAME/rmc.mca		# error output from mcassemble command
CT_CLASS_IDS=/usr/sbin/rsct/cfg/ct_class_ids
START_PORT_FILE=/var/ct/cfg/ctrmc.rpe	# rpe == remote port enable

CMD=$(basename $0)
CTMSG=${SS_PATH}/ctdspmsg
MSGMAPPATH=/usr/sbin/rsct/msgmaps
export MSGMAPPATH

# sed string to extract subsystem state from "lssrc -s <subsys>" output
PARSE_SRC_STATE="-e1d;s/.* \([a-zA-Z0-9]*\)$/\1/"

# sed string to extract subsystem PIDs from "lssrc -g <subsys>" output
PARSE_SRC_PIDS="s/^ *[^ ]* *[^ ]* *\([0-9]*\) *active/\1/p"

# get name of Operating System. How the RMC subsystem is started at bootup
# is OS dependent.

OSname=$(uname -s)
if [[ -z $OSname ]]
then
	OSname=unknown_OS
fi

# mainline code

# Parse command line

Argcount=0
while getopts ":aAskKdpPqQzh" opt
do
	case $opt in
		a )	Op=add;             Argcount=$((Argcount + 1));;
		A )	Op=Add;             Argcount=$((Argcount + 1));;
		s )	Op=start;           Argcount=$((Argcount + 1));;
		k )	Op=stop;            Argcount=$((Argcount + 1));;
		K )	Op=stopall;         Argcount=$((Argcount + 1));;
		d )	Op=delete;          Argcount=$((Argcount + 1));;
		p )	Op=startport;       Argcount=$((Argcount + 1));;
		P )	Op=stopport;        Argcount=$((Argcount + 1));;
		q )	Op=delaystartport;  Argcount=$((Argcount + 1));;
		Q )	Op=delaystopport;   Argcount=$((Argcount + 1));;
		z )	Op=stopwait;        Argcount=$((Argcount + 1));;
		h ) $CTMSG rmcctrl ct_rmc.cat INFOMsg_rmcctrl_Usage_B $CMD
				 exit 0;;
		? ) $CTMSG rmcctrl ct_rmc.cat INFOMsg_rmcctrl_Usage_B $CMD
				 exit 1;;
	esac
done

if ((Argcount == 0))
then
	$CTMSG rmcctrl ct_rmc.cat INFOMsg_rmcctrl_Usage_B $CMD
	exit 1
fi

if ((Argcount > 1))
then
	$CTMSG rmcctrl ct_rmc.cat INFOMsg_rmcctrl_Usage_B $CMD
	exit 1
fi

case $Op in

# Add the RMC subsystem to the SRC, /etc/inittab and copy the CDB

add | Add )
	# Ensure subsystem is stopped if it is already in SRC

	state=$(LC_ALL=C lssrc -s "$SUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" && "$state" = "active" ]]
	then
		$CTMSG rmcctrl ct_rmc.cat EMSGG_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYS
		exit 1
	fi

	SRC_args=

	if [[ ! -x $SS_PATH/$SPROG ]]
	then
		$CTMSG rmcctrl ct_rmc.cat EMSGG_Not_Executable $CMD $SS_PATH/$SPROG
		exit 1
	fi

	if [[ ! -x $SS_PATH/$PROG ]]
	then
		$CTMSG rmcctrl ct_rmc.cat EMSGG_Not_Executable $CMD $SS_PATH/$PROG
		exit 1
	fi

	rmssys -s $SUBSYS >/dev/null		# ensure subsystem is out of SRC

	mkssys -s $SUBSYS -a "$SRC_args" -p $SS_PATH/$SPROG -u 0 \
			-i /dev/null -o /dev/null -e /dev/null \
			-R -Q -K -d -w $WAITTIME -G $SUBSYSGRP

	if [[ $? -ne 0 ]]
	then
		$CTMSG rmcctrl ct_rmc.cat EMSGG_Could_Not_Add $CMD $SUBSYS SRC
		exit 1
	fi

	# if this is an AIX system, RMC is started out of inittab at boot

	if [[ $OSname = "AIX" ]]
	then

		# Add an entry to the inittab file for this subsystem, if it is not
		# already there. The new entry will be put at the end of /etc/inittab

		lsitab $SUBSYS > /dev/null 2>&1
		if (( $? != 0 ))                # if entry not there
		then
			mkitab \
			"$SUBSYS:2:once:/usr/bin/startsrc -s $SUBSYS > /dev/console 2>&1" \
			> /dev/null 2>&1
			if (( $? != 0))
			then
				$CTMSG rmcctrl ct_rmc.cat EMSGG_Could_Not_Add $CMD \
						$SUBSYS inittab
				exit 1
			fi
		fi
	fi

	# if this is a Linux system, RMC is started/stopped by the rc script
	# mechanism at boot or when the runlevel changes

	if [[ $OSname = "Linux" ]]
	then
		if ! $SS_PATH/ctinitmgr -a $SS_PATH/rc_$SUBSYS $SUBSYS
		then
			# NEED TO DO: create real error message
			echo "Cannot add $SUBSYS to init script structure"
			exit 1
		fi
	fi

	# assemble the CDB from the installed component parts. But first
	# remove any previous CDB and export the target directory to the
	# mcassemble command

	rm -f $CFGDIR/$CDBNAMEDST
	export RMC_MCASSEMBLE_OUTPUT_DIRECTORY=$CFGDIR
	
	# check for cdef files in the input directory before calling mcassemble

	if ls $CDEF_PATH/*.cdef > /dev/null 2>&1
	then
		if mcassemble $CT_CLASS_IDS 2> $MCALOG
		then
			rm -f $MCALOG
			mv $CFGDIR/assembled.cdb $CFGDIR/$CDBNAMEDST
			chmod 440 $CFGDIR/$CDBNAMEDST
		else
			$CTMSG rmcctrl ct_rmc.cat EMSGV_Cannot_copy_CDB $CMD $MCALOG
			exit 1
		fi
	fi

	# ensure the RMC remote port numbers are in /etc/services

	TMPSVCS=/etc/services.tmp.$$
	cp /etc/services $TMPSVCS
	Flag=0

	if ! grep 'rmc[ 	][ 	]*[0-9][0-9]*/tcp' /etc/services > /dev/null 2>&1
	then
		print "rmc\t\t657/tcp" >> $TMPSVCS
		Flag=1
	fi

	if ! grep 'rmc[ 	][ 	]*[0-9][0-9]*/udp' /etc/services > /dev/null 2>&1
	then
		print "rmc\t\t657/udp" >> $TMPSVCS
		Flag=1
	fi

	if [[ $Flag = 1 ]]
	then
		mv -f $TMPSVCS /etc/services
	else
		rm -f $TMPSVCS
	fi

	# ensure the security subsystem daemon is in SRC

	state=$(LC_ALL=C lssrc -s "$SECSUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -z "$state" || "$state" != "active" ]]
	then

		rmssys -s $SECSUBSYS >/dev/null		# ensure subsystem is out of SRC

		mkssys -s $SECSUBSYS -p $SS_PATH/$SECPROG -u 0 \
				-i /dev/null -o /dev/null -e /dev/null \
				-R -Q -S -f 15 -n 15 -d -w $WAITTIME -G $SUBSYSGRP

		if [[ $? -ne 0 ]]
		then
			$CTMSG rmcctrl ct_rmc.cat EMSGG_Could_Not_Add $CMD $SECSUBSYS SRC
			exit 1
		fi
	fi

	# start the subsystem if the -A flag was specified.

	if [[ $Op = Add ]]
	then
		startsrc -I -s $SUBSYS
		if [[ $? -eq 0 ]]
		then
			if [[ $OSname = "Linux" ]]
			then
				$SS_PATH/ctinitmgr -s $SUBSYS
			fi
		else
			exit 1
		fi
	fi

	;;

# start the subsystem 

start )
	startsrc -I -s $SUBSYS
	if [[ $? -eq 0 ]]
	then
		if [[ $OSname = "Linux" ]]
		then
			$SS_PATH/ctinitmgr -s $SUBSYS
		fi
	else
		exit 1
	fi

	;;

# stop the subsystem 

stop | stopall )
	# Stop Resource Managers if required

	if [[ $Op = stopall ]]
	then
		# get process IDs of all resource managers

		list=$(LC_ALL=C lssrc -g ${RMGRP} 2> /dev/null | grep "active" | \
			sed -n -e "$PARSE_SRC_PIDS" | tr '\n' ',')

		if [[ -n "${list}" ]]
		then
			stopsrc -c -g $RMGRP
		fi
	fi

	# Only stop subsystem if it is running

	state=$(LC_ALL=C lssrc -s "$SUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" && "$state" = "active" ]]
	then
		stopsrc -s $SUBSYS -c
		if [[ $? -eq 0 ]]
		then
			if [[ $OSname = "Linux" ]]
			then
				$SS_PATH/ctinitmgr -k $SUBSYS
			fi
		else
			exit 1
		fi
	fi

	;;

# Delete all elements of the subsystem

delete )
	# Ensure subsystem is stopped 

	state=$(LC_ALL=C lssrc -s "$SUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" && "$state" = "active" ]]
	then
		$CTMSG rmcctrl ct_rmc.cat EMSGG_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYS
		exit 1
	fi

	rmssys -s $SUBSYS >/dev/null		# take subsystem out of SRC

	if [[ $OSname = "AIX" ]]
	then
		# remove the entry from inittab

		rmitab $SUBSYS 2> /dev/null
	fi

	if [[ $OSname = "Linux" ]]
	then
		# remove the symbolic links from /etc/rc.d/rc*.d
		$SS_PATH/ctinitmgr -d $SUBSYS
	fi

	# remove CDB and related files

	rm -f $CFGDIR/${CDBBASE}*

	# remove remote port enable file

	rm -f $START_PORT_FILE

	# remove security subsystem daemon

	state=$(LC_ALL=C lssrc -s "$SECSUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" ]]
	then
		if [[ "$state" = "active" ]]
		then
			stopsrc -c -s $SECSUBSYS
		fi

		rmssys -s $SECSUBSYS >/dev/null		# take subsystem out of SRC
	fi

	;;

# enable remote client connections

startport | delaystartport )
	rm -f $START_PORT_FILE

	if [[ $Op = startport ]]
	then
		rmcstartport -s $SUBSYS
		if [[ $? -ne 0 ]]
		then
			exit 1
		fi

		state=$(LC_ALL=C lssrc -s "$SECSUBSYS" | sed "$PARSE_SRC_STATE")
		if [[ -n "$state" && "$state" != "active" ]]
		then
			startsrc -I -s $SECSUBSYS
		fi
	fi
	touch $START_PORT_FILE
	chmod 440 $START_PORT_FILE

	;;

# disable remote client connections

stopport | delaystopport)
	rm -f $START_PORT_FILE

	if [[ $Op = stopport ]]
	then
		rmcstopport -s $SUBSYS
		if [[ $? -ne 0 ]]
		then
			exit 1
		fi

		state=$(LC_ALL=C lssrc -s "$SECSUBSYS" | sed "$PARSE_SRC_STATE")
		if [[ -n "$state" && "$state" = "active" ]]
		then
			stopsrc -c -s $SECSUBSYS
		fi
	fi

	;;


# stop all RMC subsystems and wait for them to die

stopwait )

	# get process IDs of all daemons

	PROCLIST=$(LC_ALL=C lssrc -g ${SUBSYSGRP} 2> /dev/null | grep "active" | \
		sed -n -e "$PARSE_SRC_PIDS" | tr '\n' ',')

	# get process IDs of all resource managers

	list=$(LC_ALL=C lssrc -g ${RMGRP} 2> /dev/null | grep "active" | \
		sed -n -e "$PARSE_SRC_PIDS" | tr '\n' ',')

	if [[ -n "${list}" ]]
	then
		PROCLIST=${PROCLIST}${list}
	fi

	# if any daemons or RMs are running

	if [ -n "${PROCLIST}" ]
	then
		PROCLIST=${PROCLIST%,}
		stopsrc -c -g ${RMGRP} > /dev/null 2>&1
		stopsrc -c -g ${SUBSYSGRP} > /dev/null 2>&1
		(( i = ${WAITLIMIT} ))
		while (( $i > 0 ))
		do
			ps -p ${PROCLIST} > /dev/null 2>&1
			if [[ $? -ne 0 ]]
			then
				break
			else
				sleep 2
				(( i = $i - 2 ))
			fi
		done
		ps -p ${PROCLIST} > /dev/null 2>&1
		if [[ $? -eq 0 ]]
		then
			exit 2
		fi
	fi

	;;

esac

exit 0
